package de.jmetroid.ui;

import com.jme3.animation.AnimControl;
import com.jme3.app.Application;
import com.jme3.bullet.BulletAppState;
import com.jme3.font.BitmapText;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial.CullHint;
import com.jme3.system.AppSettings;

import de.jmetroid.tiles.TileFactory;

public class JMetroidApplication extends Application {

  private Node rootNode;
  private Node guiNode;
  private Node player;
  private BitmapText fpsText;
  private float secondCounter;
  private BulletAppState bulletAppState;
  private TileFactory tileFactory;

  public JMetroidApplication() {
    final AppSettings appSettings = new AppSettings(true);
    appSettings.setRenderer(AppSettings.LWJGL_OPENGL2);
    appSettings.setTitle("Java Metroid");
    appSettings.setResolution(800, 600);
    appSettings.setVSync(true);
    setSettings(appSettings);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void initialize() {
    super.initialize();
    tileFactory = new TileFactory(assetManager);
    rootNode = new Node("Root Node");
    guiNode = new Node("GUI Node");
    guiNode.setQueueBucket(Bucket.Gui);
    guiNode.setCullHint(CullHint.Never);
    viewPort.attachScene(rootNode);
    viewPort.setBackgroundColor(ColorRGBA.DarkGray);
    guiViewPort.attachScene(guiNode);
    fpsText = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt"), false);
    fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0);
    guiNode.attachChild(fpsText);
    bulletAppState = new BulletAppState();
    bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
    stateManager.attach(bulletAppState);

    for (int i = -5; i <= 5; i++) {
      tileFactory.createTile(new Vector3f((float) i, -2.0f, 0.0f), rootNode, bulletAppState.getPhysicsSpace());
    }

    player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
    player.setLocalScale(0.5f);
    rootNode.attachChild(player);
    player.getControl(AnimControl.class).createChannel().setAnim("stand");
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void update() {
    super.update();
    if (speed == 0 || paused) {
      return;
    }
    secondCounter += timer.getTimePerFrame();
    final int fps = (int) timer.getFrameRate();
    if (secondCounter >= 1.0f) {
      fpsText.setText(String.format("%d fps", fps));
      secondCounter = 0.0f;
    }
    final float tpf = timer.getTimePerFrame() * speed;
    stateManager.update(tpf);
    rootNode.updateLogicalState(tpf);
    guiNode.updateLogicalState(tpf);
    rootNode.updateGeometricState();
    guiNode.updateGeometricState();
    stateManager.render(renderManager);
    renderManager.render(tpf);
    stateManager.postRender();
  }

}
